Skip to content

Allow --copy to accept individual files alongside directories#252

Open
bcomnes wants to merge 4 commits intomasterfrom
fix/copy-files-support
Open

Allow --copy to accept individual files alongside directories#252
bcomnes wants to merge 4 commits intomasterfrom
fix/copy-files-support

Conversation

@bcomnes
Copy link
Copy Markdown
Owner

@bcomnes bcomnes commented Apr 18, 2026

--copy now accepts individual file paths in addition to directories. Directories continue to use the existing /** glob behavior. Files are passed directly to cpx2, which places them in the destination root.

# Before: sw.js was silently ignored (sw.js/** matched nothing)
domstack --copy images --copy sw.js

# After: sw.js is copied to public/sw.js
domstack --copy images --copy sw.js

Paths that cannot be stat'd (do not exist yet, or have permission issues) fall back to directory glob behavior to preserve backwards compatibility.

getCopyDirs is now async. Both buildCopy and the watch-mode watcher setup in the DomStack class have been updated to await it.

Closes #236

getCopyDirs now stats each path to determine whether it is a file or a
directory. Directories keep the existing behavior (glob appended with
/**). Files are passed as-is to cpx2, which copies them directly into
the destination root.

Paths that cannot be stat'd (not yet created, permission errors) fall
back to directory glob behavior to preserve backwards compatibility.

Closes #236
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 18, 2026

Coverage Report for CI Build 24619421759

Coverage increased (+0.03%) to 91.496%

Details

  • Coverage increased (+0.03%) from the base build.
  • Patch coverage: 1 uncovered change across 1 file (22 of 23 lines covered, 95.65%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
lib/build-copy/index.js 22 21 95.45%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 4082
Covered Lines: 3816
Line Coverage: 93.48%
Relevant Branches: 645
Covered Branches: 509
Branch Coverage: 78.91%
Branches in Coverage %: Yes
Coverage Strength: 73.45 hits per line

💛 - Coveralls

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends DomStack’s --copy option so it can handle individual files in addition to directories by stat’ing each provided path and only appending /** for directories (or paths that can’t be stat’d), then propagates the resulting async API to build and watch mode.

Changes:

  • Make getCopyDirs() async and return either dir/** (directories) or the file path as-is (files).
  • Await getCopyDirs() in buildCopy() and in DomStack.watch() watcher setup.
  • Update the existing getCopyDirs() test to use the async API.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
lib/build-copy/index.js Implements async stat-based detection to support copying files as well as directories; updates build step to await the new API.
lib/build-copy/index.test.js Updates test to await getCopyDirs() (but currently only asserts the directory-glob fallback).
index.js Updates watch-mode copy watcher setup to await getCopyDirs() before constructing cpx watchers.
Comments suppressed due to low confidence (1)

index.js:255

  • copyDirs now includes both directory globs and file paths, so the name is misleading in the watch setup. Consider renaming the local to something like copyGlobs/copyEntries to better reflect its contents.
    const copyDirs = await getCopyDirs(this.opts.copy)

    this.#cpxWatchers = [
      cpx.watch(getCopyGlob(this.#src), this.#dest, { ignore: this.opts.ignore }),
      ...copyDirs.map(copyDir => cpx.watch(copyDir, this.#dest))
    ]

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/build-copy/index.test.js
Comment thread lib/build-copy/index.js Outdated
Renames the local variable in buildCopy to copyGlobs to clarify that the
array now contains either directory globs or file paths, not just dirs.

Adds two tests: one asserting existing files are passed through as-is,
and one asserting existing directories still get /** appended.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

index.js:255

  • getCopyDirs() can now return bare file paths as well as directory globs, but this code still names the resulting list copyDirs / copyDir. Renaming these locals to copyGlobs/copySources (and copyGlob/copySource) would avoid confusion when reading or extending the watch setup.
    const copyDirs = await getCopyDirs(this.opts.copy)

    this.#cpxWatchers = [
      cpx.watch(getCopyGlob(this.#src), this.#dest, { ignore: this.opts.ignore }),
      ...copyDirs.map(copyDir => cpx.watch(copyDir, this.#dest))
    ]

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/build-copy/index.js Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

index.js:255

  • In watch mode, copyDirs now contains a mix of directory globs (".../**") and file paths. Renaming this local (and the copyDir loop variable) to copyGlobs/copyPaths would better reflect what is being watched/copied and align with the naming already used in buildCopy().
    // ── Copy watchers & browser-sync ─────────────────────────────────────
    const copyDirs = await getCopyDirs(this.opts.copy)

    this.#cpxWatchers = [
      cpx.watch(getCopyGlob(this.#src), this.#dest, { ignore: this.opts.ignore }),
      ...copyDirs.map(copyDir => cpx.watch(copyDir, this.#dest))
    ]

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/build-copy/index.test.js Outdated
Comment thread lib/build-copy/index.js
…ile support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow --copy to handle individual files, not just directories

3 participants